/*
 *  Filename:      app.c
 *  Author:         Erick Huang<erickhuang1989@gmail.com>
 *  Revised:        2014-12-23
 *  Description:   This file contains a sample application.
 *
 *  Copyright (c) Erick Huang. All rights reserved.
 */
#include "meos_api.h"
#include "hal_board.h"
#include "meos_protocol.h"
#include "app.h"

static void App_ProcessMEOSMsg( meos_msg_data_hdr_t *pMsg );
static void App_ProcessUserMsg( UserMsgPacket_t *pMsg );
static void App_HandleKeys( uint8 shift, uint8 keys );
static void App_ProtEventCB( ProtEvent_t *pEvent );


// Protocol Callbacks
static const ProtCBs_t protCBs =
{
  	App_ProtEventCB,       // Event callback
	NULL
};

/* Task ID for internal task/event processing */
uint8 App_TaskID;

/*********************************************************************
 * @fn      App_Init
 *
 * @brief   Initialization function for the  App Task.
 *          This is called during initialization and should contain any application specific initialization
 *          (ie. hardware initialization/setup, table initialization, power up notificaiton ... ).
 *
 * @param   task_id - the ID assigned by MEOS.  This ID should be
 *                    used to send messages and set timers.
 *
 * @return  none
 */
void App_Init( uint8 task_id )
{
	App_TaskID = task_id;

	// Register to receive incoming message
  	Prot_RegisterForMsg( App_TaskID );

	// Register for all key events - This app will handle all key events
  	RegisterForKeys( App_TaskID );

	// Setup a delayed profile startup
	meos_start_timerEx( App_TaskID, APP_START_DEVICE_EVT, APP_STARTDELAY );
}

/*********************************************************************
 * @fn      App_ProcessEvent
 *
 * @brief   Application Task event processor.  
 *            This function is called to process all events for the task.  
 *            Events include timers, messages and any other user defined events.
 *
 * @param   task_id  - The MEOS assigned task ID.
 * @param   events - events to process.  This is a bit map and can contain more than one event.
 *
 * @return  events not processed
 */
uint16 App_ProcessEvent( uint8 task_id, uint16 events )
{
	VOID task_id;

	if ( events & SYS_EVENT_MSG )
  	{
    	uint8 *pMsg;

    	if ( (pMsg = meos_msg_receive( App_TaskID )) != NULL )
    	{
      		App_ProcessMEOSMsg( (meos_msg_data_hdr_t *)pMsg );

      		// Release the OSAL message
      		meos_msg_deallocate( pMsg );
    	}

    	// return unprocessed events
    	return (events ^ SYS_EVENT_MSG);
  	}

	if ( events & APP_START_DEVICE_EVT )
	{
		// Start the Device
		Prot_Start(( (ProtCBs_t *)&protCBs) );

		// Set timer for first periodic event
    	meos_start_timerEx( App_TaskID,  APP_PERIODIC_EVT, APP_PERIODIC_EVT_PERIOD );

		// return unprocessed events
    	return (events ^ APP_START_DEVICE_EVT);
	}

	if ( events & APP_PERIODIC_EVT )
	{
		// Restart timer
	 	if ( APP_PERIODIC_EVT_PERIOD )
	 	{
	   		meos_start_timerEx( App_TaskID, APP_PERIODIC_EVT, APP_PERIODIC_EVT_PERIOD );
	 	}
  
	 	// Perform periodic application task

		// return unprocessed events
    	return (events ^ APP_PERIODIC_EVT);
	}

	// Discard unknown events
	return 0;
}

static void App_ProcessMEOSMsg( meos_msg_data_hdr_t *pMsg )
{
  	switch ( pMsg->type )
  	{
    	case MSG_TYPE_KEY_CHANGE:
      		App_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
      		break;
		case MSG_TYPE_USER_APP_MSG:
			App_ProcessUserMsg( (UserMsgPacket_t *)pMsg );
			break;

  		default:
    		// do nothing
    		break;
  	}
}

static void App_ProcessUserMsg( UserMsgPacket_t *pMsg )
{
  	switch ( pMsg->method )
  	{

  		default:
    		// do nothing
    		break;
  	}
}

static void App_HandleKeys( uint8 shift, uint8 keys )
{
  	VOID shift;
	VOID keys;
}

static void App_ProtEventCB( ProtEvent_t *pEvent )
{
	uint8 data;
  	switch ( pEvent->prot.opcode )
  	{
		case PROT_EVENT_INIT_DONE:  
      	{
			data = pEvent->initDone.data;
      	}
      	break;
  	}
}

